"""
系统设置配置

使用Pydantic Settings管理所有系统配置，支持从环境变量、
配置文件等多种来源读取配置。
"""

from typing import Optional, List
from pydantic import Field, validator
from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    """系统配置类"""
    
    # 应用基础配置
    app_name: str = Field(default="AI量化投研系统", description="应用名称")
    app_version: str = Field(default="0.1.0", description="应用版本")
    debug: bool = Field(default=False, description="调试模式")
    environment: str = Field(default="production", description="运行环境")
    
    # API配置
    api_host: str = Field(default="0.0.0.0", description="API主机地址")
    api_port: int = Field(default=8000, description="API端口")
    api_prefix: str = Field(default="/api/v1", description="API路径前缀")
    
    # 数据库配置
    database_url: str = Field(
        default="postgresql+asyncpg://username:password@localhost:5432/aiquant",
        description="主数据库连接URL"
    )
    database_pool_size: int = Field(default=20, description="数据库连接池大小")
    database_max_overflow: int = Field(default=30, description="数据库连接池最大溢出")
    
    # TimescaleDB配置
    timescale_url: str = Field(
        default="postgresql+asyncpg://username:password@localhost:5432/aiquant_timeseries",
        description="时序数据库连接URL"
    )
    
    # Redis配置
    redis_url: str = Field(default="redis://localhost:6379/0", description="Redis连接URL")
    redis_password: Optional[str] = Field(default=None, description="Redis密码")
    redis_db: int = Field(default=0, description="Redis数据库编号")
    
    # 安全配置
    secret_key: str = Field(
        default="your-secret-key-here-change-in-production",
        description="JWT密钥"
    )
    algorithm: str = Field(default="HS256", description="JWT算法")
    access_token_expire_minutes: int = Field(default=30, description="访问令牌过期时间(分钟)")
    
    # 日志配置
    log_level: str = Field(default="INFO", description="日志级别")
    log_format: str = Field(default="json", description="日志格式")
    log_file: str = Field(default="logs/app.log", description="日志文件路径")
    
    # CrewAI配置
    crewai_api_key: Optional[str] = Field(default=None, description="CrewAI API密钥")
    crewai_model: str = Field(default="gpt-4", description="CrewAI默认模型")
    
    # LangGraph配置
    langgraph_api_key: Optional[str] = Field(default=None, description="LangGraph API密钥")
    
    # 外部API配置
    wind_api_key: Optional[str] = Field(default=None, description="Wind API密钥")
    bloomberg_api_key: Optional[str] = Field(default=None, description="Bloomberg API密钥")
    tushare_token: Optional[str] = Field(default=None, description="Tushare Token")
    
    # 大语言模型配置
    openai_api_key: Optional[str] = Field(default=None, description="OpenAI API密钥")
    openai_base_url: str = Field(default="https://api.openai.com/v1", description="OpenAI API基础URL")
    anthropic_api_key: Optional[str] = Field(default=None, description="Anthropic API密钥")
    
    # 消息队列配置
    celery_broker_url: str = Field(default="redis://localhost:6379/1", description="Celery代理URL")
    celery_result_backend: str = Field(default="redis://localhost:6379/2", description="Celery结果后端")
    
    # 监控配置
    prometheus_port: int = Field(default=9090, description="Prometheus端口")
    grafana_port: int = Field(default=3000, description="Grafana端口")
    
    # 邮件配置
    smtp_host: str = Field(default="smtp.gmail.com", description="SMTP主机")
    smtp_port: int = Field(default=587, description="SMTP端口")
    smtp_user: Optional[str] = Field(default=None, description="SMTP用户名")
    smtp_password: Optional[str] = Field(default=None, description="SMTP密码")
    smtp_tls: bool = Field(default=True, description="SMTP TLS")
    
    # 文件存储配置
    upload_dir: str = Field(default="uploads", description="上传目录")
    max_file_size: int = Field(default=10485760, description="最大文件大小(字节)")
    
    # 缓存配置
    cache_ttl: int = Field(default=3600, description="缓存TTL(秒)")
    cache_prefix: str = Field(default="aiquant:", description="缓存前缀")
    
    # 限流配置
    rate_limit_per_minute: int = Field(default=60, description="每分钟请求限制")
    rate_limit_per_hour: int = Field(default=1000, description="每小时请求限制")
    
    # 系统配置
    timezone: str = Field(default="Asia/Shanghai", description="时区")
    locale: str = Field(default="zh_CN.UTF-8", description="本地化")
    
    @validator("environment")
    def validate_environment(cls, v: str) -> str:
        """验证环境配置"""
        allowed_envs = ["development", "testing", "staging", "production"]
        if v not in allowed_envs:
            raise ValueError(f"环境必须是以下之一: {allowed_envs}")
        return v
    
    @validator("log_level")
    def validate_log_level(cls, v: str) -> str:
        """验证日志级别"""
        allowed_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
        if v.upper() not in allowed_levels:
            raise ValueError(f"日志级别必须是以下之一: {allowed_levels}")
        return v.upper()
    
    @validator("api_port", "prometheus_port", "grafana_port", "smtp_port")
    def validate_port(cls, v: int) -> int:
        """验证端口号"""
        if not (1 <= v <= 65535):
            raise ValueError("端口号必须在1-65535之间")
        return v
    
    class Config:
        """Pydantic配置"""
        env_file = ".env"
        env_file_encoding = "utf-8"
        case_sensitive = False
        
    def get_database_url(self, async_driver: bool = True) -> str:
        """获取数据库连接URL"""
        if async_driver:
            return self.database_url
        else:
            return self.database_url.replace("+asyncpg", "")
    
    def get_redis_url(self) -> str:
        """获取Redis连接URL"""
        if self.redis_password:
            return f"redis://:{self.redis_password}@{self.redis_url.split('@')[-1]}"
        return self.redis_url
    
    def is_development(self) -> bool:
        """是否为开发环境"""
        return self.environment == "development"
    
    def is_production(self) -> bool:
        """是否为生产环境"""
        return self.environment == "production"


# 创建全局设置实例
settings = Settings()


def get_settings() -> Settings:
    """获取设置实例"""
    return settings